namespace Ocelot.Middleware
{
    using iTool.ClusterComponent;
    using Microsoft.AspNetCore.Http;
    using Ocelot.Configuration.Repository;
    using Ocelot.Errors.Middleware;
    using Ocelot.Logging;
    using System.Linq;
    using System.Threading.Tasks;

    public class ConfigurationMiddleware : OcelotMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IInternalConfigurationRepository _configRepo;
        private IHttpRequestStatisticsService iHttpRequestStatisticsService;

        public ConfigurationMiddleware(RequestDelegate next, IOcelotLoggerFactory loggerFactory, IInternalConfigurationRepository configRepo)
            : base(loggerFactory.CreateLogger<ExceptionHandlerMiddleware>())
        {
            _next = next;
            _configRepo = configRepo;
        }

        public async Task Invoke(HttpContext httpContext)
        {

            var requestInfo = new RequestInfo();

            //todo check the config is actually ok?
            var config = _configRepo.Get();

            if (config.IsError)
            {
                throw new System.Exception("OOOOPS this should not happen raise an issue in GitHub");
            }

            requestInfo.Template = config.Data.Routes.FirstOrDefault()?.UpstreamTemplatePattern?.Template;
            requestInfo.URL = httpContext.Request.Path;

            IClusterService clusterService = ServerProvider.GetService<IClusterService>("IDashboardService");

            try
            {
                httpContext.Items.SetIInternalConfiguration(config.Data);
                await _next.Invoke(httpContext);
                requestInfo.RequestSucceeded();
            }
            catch (System.Exception ex)
            {
                requestInfo.RequestError(ex);
            }

            if (clusterService != null)
            {
                if (this.iHttpRequestStatisticsService == null)
                {
                    this.iHttpRequestStatisticsService = clusterService.GetService<IHttpRequestStatisticsService>();
                }

                try
                {
                    await this.iHttpRequestStatisticsService.RequestAsync(requestInfo);
                }
                catch (System.Exception)
                {
                    this.iHttpRequestStatisticsService = null;
                }
            }

        }
    }
}
